package corp.edu.amadeus.core.dao.impl.callback;

import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import corp.edu.amadeus.core.dao.impl.Parameter;

/**
 * @author Eduardo Perrino
 */
public class FindByNamedQueryCallback implements HibernateCallback {


    private final String query;
    private final Collection params;
    private final static int DEFAULT = -9999;
    private final int first;
    private final int last;
    private final Class target;

    /**
     *
     */
    public FindByNamedQueryCallback(final String query) {
        super();
        this.query = query;
        this.params = null;
        this.target = null;
        first = last = DEFAULT;
    }


    public FindByNamedQueryCallback(final String query, final Collection params) {
        super();
        this.query = query;
        this.params = params;
        this.target = null;
        first = last = DEFAULT;
    }

    public FindByNamedQueryCallback(final Class target, final Collection params,
        final int first, final int last) {
        super();
        this.target = target;
        this.query = null;
        this.params = params;
        this.first = first;
        this.last = last;
    }

    /**
     *
     */
    public Object doInHibernate(Session session) throws HibernateException,
        SQLException {

        Query query = session.getNamedQuery(this.query);
        if (this.params != null) {
            Iterator it = params.iterator();
            while (it.hasNext()) {
                ((Parameter)it.next()).addToQuery(query);
            }
        }

        if (this.target != null) {
            Criteria criteria = session.createCriteria(target);
            if (first != DEFAULT) {
                criteria.setFirstResult(first);
            }

            if (last != DEFAULT) {
                criteria.setMaxResults(last);
            }
        }

        return query.list();
    }

}
